{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from keras.models import Model\n",
    "from keras.layers import Input\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras import backend as K\n",
    "import json\n",
    "from collections import OrderedDict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def format_decimal(arr, places=8):\n",
    "    return [round(x * 10**places) / 10**places for x in arr]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "DATA = OrderedDict()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### BatchNormalization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.0] epsilon=1e-05, axis=-1, center=True, scale=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gamma shape: (3,)\n",
      "gamma: [0.30717917, -0.76998611, 0.90056573]\n",
      "beta shape: (3,)\n",
      "beta: [-0.38753564, -0.46987287, -0.60787987]\n",
      "moving_mean shape: (3,)\n",
      "moving_mean: [-0.74202342, -0.07768763, -0.16769214]\n",
      "moving_variance shape: (3,)\n",
      "moving_variance: [0.5978058, 0.43593379, 0.01686999]\n",
      "\n",
      "in shape: (4, 3)\n",
      "in: [0.19337492, 0.7899562, 0.06925513, -0.98808939, 0.80435901, 0.50903924, -0.65579245, 0.46005824, -0.25374991, -0.63537441, -0.10931755, -0.42626602]\n",
      "out shape: (4, 3)\n",
      "out: [-0.01591084, -1.48170662, 1.03452778, -0.48529527, -1.49850297, 4.08290577, -0.35327691, -1.09698439, -1.20439208, -0.34516501, -0.4329865, -2.40019298]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3)\n",
    "norm = BatchNormalization(epsilon=1e-05, axis=-1, center=True, scale=True)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1000 + i)\n",
    "    if i == 3:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('gamma shape:', weights[0].shape)\n",
    "print('gamma:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('beta shape:', weights[1].shape)\n",
    "print('beta:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[2].shape)\n",
    "print('moving_mean:', format_decimal(weights[2].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[3].shape)\n",
    "print('moving_variance:', format_decimal(weights[3].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.0'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.1] epsilon=1e-02, axis=-1, center=True, scale=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gamma shape: (3,)\n",
      "gamma: [-0.21148703, -0.64881506, -0.85458828]\n",
      "beta shape: (3,)\n",
      "beta: [0.31136173, -0.22851883, 0.25302429]\n",
      "moving_mean shape: (3,)\n",
      "moving_mean: [-0.94654129, 0.58559264, -0.49527049]\n",
      "moving_variance shape: (3,)\n",
      "moving_variance: [0.55703859, 0.05517086, 0.26398732]\n",
      "\n",
      "in shape: (4, 3)\n",
      "in: [0.71880835, -0.1596278, -0.95536448, -0.94580233, -0.43370689, -0.55992129, 0.41852567, 0.03566775, 0.0999246, 0.53704832, 0.9145912, -0.50412891]\n",
      "out shape: (4, 3)\n",
      "out: [-0.15635495, 1.66547668, 1.00419426, 0.31115419, 2.3620553, 0.358576, -0.07201998, 1.16912842, -0.71871787, -0.1053073, -1.06467664, 0.26748699]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3)\n",
    "norm = BatchNormalization(epsilon=1e-02, axis=-1, center=True, scale=True)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1010 + i)\n",
    "    if i == 3:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('gamma shape:', weights[0].shape)\n",
    "print('gamma:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('beta shape:', weights[1].shape)\n",
    "print('beta:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[2].shape)\n",
    "print('moving_mean:', format_decimal(weights[2].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[3].shape)\n",
    "print('moving_variance:', format_decimal(weights[3].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.1'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.2] epsilon=1e-05, axis=1, center=True, scale=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gamma shape: (4,)\n",
      "gamma: [0.51790609, -0.66653736, 0.37866461, -0.38006242]\n",
      "beta shape: (4,)\n",
      "beta: [0.40055717, 0.74387118, 0.43713362, -0.55480014]\n",
      "moving_mean shape: (4,)\n",
      "moving_mean: [-0.72639303, 0.96140456, -0.35265082, -0.61683149]\n",
      "moving_variance shape: (4,)\n",
      "moving_variance: [0.91406979, 0.63007121, 0.50893322, 0.05289729]\n",
      "\n",
      "in shape: (4, 3, 2)\n",
      "in: [-0.92002272, 0.46666412, 0.33270192, 0.69369639, -0.70539125, 0.38574141, 0.2966058, 0.80575415, -0.87667886, -0.14090813, -0.81737496, 0.22243293, -0.40642584, 0.14401339, 0.56671486, 0.21548293, -0.18429046, 0.90187812, 0.31491955, -0.56054439, 0.98960233, 0.26554054, 0.75526676, 0.66461658]\n",
      "out shape: (4, 3, 2)\n",
      "out: [0.29566789, 1.04683638, 0.97426903, 1.16981983, 0.41193381, 1.00300062, 1.30210531, 0.87457144, 2.28731728, 1.66948748, 2.23751926, 1.36438859, 0.40859056, 0.70075637, 0.92512071, 0.73869145, 0.52649707, 1.10302091, -2.09436178, -0.64780515, -3.20916128, -2.01277113, -2.8219614, -2.67217731]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3, 2)\n",
    "norm = BatchNormalization(epsilon=1e-05, axis=1, center=True, scale=True)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1020 + i)\n",
    "    if i == 3:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('gamma shape:', weights[0].shape)\n",
    "print('gamma:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('beta shape:', weights[1].shape)\n",
    "print('beta:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[2].shape)\n",
    "print('moving_mean:', format_decimal(weights[2].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[3].shape)\n",
    "print('moving_variance:', format_decimal(weights[3].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.2'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.3] epsilon=1e-05, axis=2, center=True, scale=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gamma shape: (3,)\n",
      "gamma: [-0.08987256, -0.21030534, -0.5544436]\n",
      "beta shape: (3,)\n",
      "beta: [-0.99796406, -0.48734278, -0.35036232]\n",
      "moving_mean shape: (3,)\n",
      "moving_mean: [-0.14543666, 0.11871984, -0.36856312]\n",
      "moving_variance shape: (3,)\n",
      "moving_variance: [0.48693282, 0.58735461, 0.51704096]\n",
      "\n",
      "in shape: (4, 3, 2)\n",
      "in: [0.17723912, -0.81800371, -0.95525628, -0.62524101, 0.9361622, 0.47178858, -0.25140505, 0.6715247, -0.81975913, 0.46866456, 0.49221768, 0.01473235, -0.4159851, 0.35468316, -0.44554467, -0.40155922, 0.68942038, 0.30257063, -0.24790617, -0.87167286, -0.15334632, -0.94018827, 0.92413894, 0.55480878]\n",
      "out shape: (4, 3, 2)\n",
      "out: [-1.03952205, -0.91134298, -0.19263539, -0.28319412, -1.35638976, -0.99832773, -0.98431623, -1.10318196, -0.22981687, -0.58337033, -1.01407993, -0.64590788, -0.96311969, -1.06237543, -0.33250421, -0.34457415, -1.16613591, -0.86784983, -0.98476684, -0.90443087, -0.41268572, -0.19677016, -1.34711909, -1.06234169]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3, 2)\n",
    "norm = BatchNormalization(epsilon=1e-05, axis=2, center=True, scale=True)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1030 + i)\n",
    "    if i == 3:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('gamma shape:', weights[0].shape)\n",
    "print('gamma:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('beta shape:', weights[1].shape)\n",
    "print('beta:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[2].shape)\n",
    "print('moving_mean:', format_decimal(weights[2].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[3].shape)\n",
    "print('moving_variance:', format_decimal(weights[3].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.3'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.4] epsilon=1e-05, axis=3, center=True, scale=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "beta shape: (2,)\n",
      "beta: [0.6605443, -0.04771633]\n",
      "moving_mean shape: (2,)\n",
      "moving_mean: [-0.95665551, 0.1278139]\n",
      "moving_variance shape: (2,)\n",
      "moving_variance: [0.32031337, 0.14493475]\n",
      "\n",
      "in shape: (4, 3, 2)\n",
      "in: [0.64108404, -0.67698454, 0.90018603, -0.32716791, -0.69711497, 0.3571678, -0.53864991, 0.94118592, 0.90909098, -0.35280573, -0.50526634, -0.61466515, -0.66641796, 0.25639848, -0.50969593, -0.75285121, 0.34839266, 0.46978101, -0.1664059, -0.08380992, 0.63740243, -0.02691944, -0.09122654, -0.79602303]\n",
      "out shape: (4, 3, 2)\n",
      "out: [3.48354912, -2.16162324, 3.94134998, -1.24278474, 1.11911988, 0.55471134, 1.39910769, 2.08871031, 3.95708394, -1.31012583, 1.45809221, -1.99793351, 1.17335761, 0.29002765, 1.45026565, -2.36089683, 2.96640038, 0.8505044, 2.0568161, -0.60357362, 3.47704434, -0.45414343, 2.18964863, -2.47429323]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3, 2)\n",
    "norm = BatchNormalization(epsilon=1e-05, axis=3, center=True, scale=False)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1040 + i)\n",
    "    if i == 2:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('beta shape:', weights[0].shape)\n",
    "print('beta:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[1].shape)\n",
    "print('moving_mean:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[2].shape)\n",
    "print('moving_variance:', format_decimal(weights[2].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.4'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.5] epsilon=1e-05, axis=-1, center=False, scale=True**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gamma shape: (2,)\n",
      "gamma: [0.8332942, -0.73282841]\n",
      "moving_mean shape: (2,)\n",
      "moving_mean: [0.01371764, -0.84259866]\n",
      "moving_variance shape: (2,)\n",
      "moving_variance: [0.66551526, 0.38091611]\n",
      "\n",
      "in shape: (4, 3, 2)\n",
      "in: [0.29214552, -0.66840164, 0.52167053, 0.49733931, 0.88648322, 0.55305475, 0.0485971, -0.33068467, 0.11495103, 0.26902905, -0.43824223, 0.98597112, 0.8185068, -0.38642272, -0.02336415, 0.39224186, 0.95561884, 0.66953993, -0.85531119, 0.83512858, 0.60595255, 0.04343527, -0.48985708, 0.45544707]\n",
      "out shape: (4, 3, 2)\n",
      "out: [0.28439951, -0.20683438, 0.51884729, -1.59098697, 0.89148432, -1.65714121, 0.03562754, -0.60782552, 0.1034046, -1.31990075, -0.46165335, -2.17116809, 0.82204998, -0.54164445, -0.03787711, -1.46619856, 0.96210277, -1.79545081, -0.88766748, -1.992064, 0.60493696, -1.0520401, -0.51437521, -1.54124582]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3, 2)\n",
    "norm = BatchNormalization(epsilon=1e-05, axis=-1, center=False, scale=True)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1050 + i)\n",
    "    if i == 2:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('gamma shape:', weights[0].shape)\n",
    "print('gamma:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('moving_mean shape:', weights[1].shape)\n",
    "print('moving_mean:', format_decimal(weights[1].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[2].shape)\n",
    "print('moving_variance:', format_decimal(weights[2].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.5'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[normalization.BatchNormalization.6] epsilon=0.001, axis=-1, center=False, scale=False**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "moving_mean shape: (2,)\n",
      "moving_mean: [0.12870543, -0.95606727]\n",
      "moving_variance shape: (2,)\n",
      "moving_variance: [0.41595926, 0.00524988]\n",
      "\n",
      "in shape: (4, 3, 2)\n",
      "in: [-0.09731108, -0.49690708, 0.92191878, -0.77721125, -0.94202527, -0.89542274, 0.78510398, 0.47090425, -0.60424113, 0.33366004, 0.16897797, 0.86414392, -0.97380934, 0.98724401, 0.72680442, 0.74601726, 0.80377242, -0.69024304, -0.78895346, -0.89545572, -0.37614091, -0.69877677, 0.11618973, 0.78171578]\n",
      "out shape: (4, 3, 2)\n",
      "out: [-0.35002038, 5.80802298, 1.22840953, 2.26239109, -1.65818667, 0.76710606, 1.01653147, 18.0500927, -1.13507748, 16.3140583, 0.06236805, 23.02427101, -1.70740914, 24.5813942, 0.92624581, 21.53005981, 1.04544234, 3.36247158, -1.42113221, 0.7666893, -0.78183013, 3.25452614, -0.01938242, 21.98161888]\n"
     ]
    }
   ],
   "source": [
    "data_in_shape = (4, 3, 2)\n",
    "norm = BatchNormalization(epsilon=0.001, axis=-1, center=False, scale=False)\n",
    "\n",
    "layer_0 = Input(shape=data_in_shape)\n",
    "layer_1 = norm(layer_0)\n",
    "model = Model(inputs=layer_0, outputs=layer_1)\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(1060 + i)\n",
    "    if i == 1:\n",
    "        # variance should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "print('moving_mean shape:', weights[0].shape)\n",
    "print('moving_mean:', format_decimal(weights[0].ravel().tolist()))\n",
    "print('moving_variance shape:', weights[1].shape)\n",
    "print('moving_variance:', format_decimal(weights[1].ravel().tolist()))\n",
    "\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "print('')\n",
    "print('in shape:', data_in_shape)\n",
    "print('in:', data_in_formatted)\n",
    "print('out shape:', data_out_shape)\n",
    "print('out:', data_out_formatted)\n",
    "\n",
    "DATA['normalization.BatchNormalization.6'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### export for Keras.js tests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "filename = '../../../test/data/layers/normalization/BatchNormalization.json'\n",
    "if not os.path.exists(os.path.dirname(filename)):\n",
    "    os.makedirs(os.path.dirname(filename))\n",
    "with open(filename, 'w') as f:\n",
    "    json.dump(DATA, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"normalization.BatchNormalization.0\": {\"input\": {\"data\": [0.19337492, 0.7899562, 0.06925513, -0.98808939, 0.80435901, 0.50903924, -0.65579245, 0.46005824, -0.25374991, -0.63537441, -0.10931755, -0.42626602], \"shape\": [4, 3]}, \"weights\": [{\"data\": [0.30717917, -0.76998611, 0.90056573], \"shape\": [3]}, {\"data\": [-0.38753564, -0.46987287, -0.60787987], \"shape\": [3]}, {\"data\": [-0.74202342, -0.07768763, -0.16769214], \"shape\": [3]}, {\"data\": [0.5978058, 0.43593379, 0.01686999], \"shape\": [3]}], \"expected\": {\"data\": [-0.01591084, -1.48170662, 1.03452778, -0.48529527, -1.49850297, 4.08290577, -0.35327691, -1.09698439, -1.20439208, -0.34516501, -0.4329865, -2.40019298], \"shape\": [4, 3]}}, \"normalization.BatchNormalization.1\": {\"input\": {\"data\": [0.71880835, -0.1596278, -0.95536448, -0.94580233, -0.43370689, -0.55992129, 0.41852567, 0.03566775, 0.0999246, 0.53704832, 0.9145912, -0.50412891], \"shape\": [4, 3]}, \"weights\": [{\"data\": [-0.21148703, -0.64881506, -0.85458828], \"shape\": [3]}, {\"data\": [0.31136173, -0.22851883, 0.25302429], \"shape\": [3]}, {\"data\": [-0.94654129, 0.58559264, -0.49527049], \"shape\": [3]}, {\"data\": [0.55703859, 0.05517086, 0.26398732], \"shape\": [3]}], \"expected\": {\"data\": [-0.15635495, 1.66547668, 1.00419426, 0.31115419, 2.3620553, 0.358576, -0.07201998, 1.16912842, -0.71871787, -0.1053073, -1.06467664, 0.26748699], \"shape\": [4, 3]}}, \"normalization.BatchNormalization.2\": {\"input\": {\"data\": [-0.92002272, 0.46666412, 0.33270192, 0.69369639, -0.70539125, 0.38574141, 0.2966058, 0.80575415, -0.87667886, -0.14090813, -0.81737496, 0.22243293, -0.40642584, 0.14401339, 0.56671486, 0.21548293, -0.18429046, 0.90187812, 0.31491955, -0.56054439, 0.98960233, 0.26554054, 0.75526676, 0.66461658], \"shape\": [4, 3, 2]}, \"weights\": [{\"data\": [0.51790609, -0.66653736, 0.37866461, -0.38006242], \"shape\": [4]}, {\"data\": [0.40055717, 0.74387118, 0.43713362, -0.55480014], \"shape\": [4]}, {\"data\": [-0.72639303, 0.96140456, -0.35265082, -0.61683149], \"shape\": [4]}, {\"data\": [0.91406979, 0.63007121, 0.50893322, 0.05289729], \"shape\": [4]}], \"expected\": {\"data\": [0.29566789, 1.04683638, 0.97426903, 1.16981983, 0.41193381, 1.00300062, 1.30210531, 0.87457144, 2.28731728, 1.66948748, 2.23751926, 1.36438859, 0.40859056, 0.70075637, 0.92512071, 0.73869145, 0.52649707, 1.10302091, -2.09436178, -0.64780515, -3.20916128, -2.01277113, -2.8219614, -2.67217731], \"shape\": [4, 3, 2]}}, \"normalization.BatchNormalization.3\": {\"input\": {\"data\": [0.17723912, -0.81800371, -0.95525628, -0.62524101, 0.9361622, 0.47178858, -0.25140505, 0.6715247, -0.81975913, 0.46866456, 0.49221768, 0.01473235, -0.4159851, 0.35468316, -0.44554467, -0.40155922, 0.68942038, 0.30257063, -0.24790617, -0.87167286, -0.15334632, -0.94018827, 0.92413894, 0.55480878], \"shape\": [4, 3, 2]}, \"weights\": [{\"data\": [-0.08987256, -0.21030534, -0.5544436], \"shape\": [3]}, {\"data\": [-0.99796406, -0.48734278, -0.35036232], \"shape\": [3]}, {\"data\": [-0.14543666, 0.11871984, -0.36856312], \"shape\": [3]}, {\"data\": [0.48693282, 0.58735461, 0.51704096], \"shape\": [3]}], \"expected\": {\"data\": [-1.03952205, -0.91134298, -0.19263539, -0.28319412, -1.35638976, -0.99832773, -0.98431623, -1.10318196, -0.22981687, -0.58337033, -1.01407993, -0.64590788, -0.96311969, -1.06237543, -0.33250421, -0.34457415, -1.16613591, -0.86784983, -0.98476684, -0.90443087, -0.41268572, -0.19677016, -1.34711909, -1.06234169], \"shape\": [4, 3, 2]}}, \"normalization.BatchNormalization.4\": {\"input\": {\"data\": [0.64108404, -0.67698454, 0.90018603, -0.32716791, -0.69711497, 0.3571678, -0.53864991, 0.94118592, 0.90909098, -0.35280573, -0.50526634, -0.61466515, -0.66641796, 0.25639848, -0.50969593, -0.75285121, 0.34839266, 0.46978101, -0.1664059, -0.08380992, 0.63740243, -0.02691944, -0.09122654, -0.79602303], \"shape\": [4, 3, 2]}, \"weights\": [{\"data\": [0.6605443, -0.04771633], \"shape\": [2]}, {\"data\": [-0.95665551, 0.1278139], \"shape\": [2]}, {\"data\": [0.32031337, 0.14493475], \"shape\": [2]}], \"expected\": {\"data\": [3.48354912, -2.16162324, 3.94134998, -1.24278474, 1.11911988, 0.55471134, 1.39910769, 2.08871031, 3.95708394, -1.31012583, 1.45809221, -1.99793351, 1.17335761, 0.29002765, 1.45026565, -2.36089683, 2.96640038, 0.8505044, 2.0568161, -0.60357362, 3.47704434, -0.45414343, 2.18964863, -2.47429323], \"shape\": [4, 3, 2]}}, \"normalization.BatchNormalization.5\": {\"input\": {\"data\": [0.29214552, -0.66840164, 0.52167053, 0.49733931, 0.88648322, 0.55305475, 0.0485971, -0.33068467, 0.11495103, 0.26902905, -0.43824223, 0.98597112, 0.8185068, -0.38642272, -0.02336415, 0.39224186, 0.95561884, 0.66953993, -0.85531119, 0.83512858, 0.60595255, 0.04343527, -0.48985708, 0.45544707], \"shape\": [4, 3, 2]}, \"weights\": [{\"data\": [0.8332942, -0.73282841], \"shape\": [2]}, {\"data\": [0.01371764, -0.84259866], \"shape\": [2]}, {\"data\": [0.66551526, 0.38091611], \"shape\": [2]}], \"expected\": {\"data\": [0.28439951, -0.20683438, 0.51884729, -1.59098697, 0.89148432, -1.65714121, 0.03562754, -0.60782552, 0.1034046, -1.31990075, -0.46165335, -2.17116809, 0.82204998, -0.54164445, -0.03787711, -1.46619856, 0.96210277, -1.79545081, -0.88766748, -1.992064, 0.60493696, -1.0520401, -0.51437521, -1.54124582], \"shape\": [4, 3, 2]}}, \"normalization.BatchNormalization.6\": {\"input\": {\"data\": [-0.09731108, -0.49690708, 0.92191878, -0.77721125, -0.94202527, -0.89542274, 0.78510398, 0.47090425, -0.60424113, 0.33366004, 0.16897797, 0.86414392, -0.97380934, 0.98724401, 0.72680442, 0.74601726, 0.80377242, -0.69024304, -0.78895346, -0.89545572, -0.37614091, -0.69877677, 0.11618973, 0.78171578], \"shape\": [4, 3, 2]}, \"weights\": [{\"data\": [0.12870543, -0.95606727], \"shape\": [2]}, {\"data\": [0.41595926, 0.00524988], \"shape\": [2]}], \"expected\": {\"data\": [-0.35002038, 5.80802298, 1.22840953, 2.26239109, -1.65818667, 0.76710606, 1.01653147, 18.0500927, -1.13507748, 16.3140583, 0.06236805, 23.02427101, -1.70740914, 24.5813942, 0.92624581, 21.53005981, 1.04544234, 3.36247158, -1.42113221, 0.7666893, -0.78183013, 3.25452614, -0.01938242, 21.98161888], \"shape\": [4, 3, 2]}}}\n"
     ]
    }
   ],
   "source": [
    "print(json.dumps(DATA))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
